home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / 80x0393.zip / VIDTYPE.ASM < prev    next >
Assembly Source File  |  1993-06-20  |  37KB  |  1,111 lines

  1. comment *
  2.  
  3.         Author:
  4.         Yousuf J. Khan
  5.  
  6.         Purpose:
  7.         To detect what type of video adapter is installed.
  8.  
  9.         Note:
  10.         Work was based on source code inside Richard Wilton's
  11.         "Programmer's Guide to PC & PS/2 Video Systems" book. However
  12.         it's been heavily reworked to a more (dare I say?)
  13.         understandable format. Also Super VGA tests were put in,
  14.         something completely missing from Wilton's book.
  15.  
  16.         *
  17.  
  18. .model tiny
  19.  
  20. ;.stack 200h
  21.  
  22. .data
  23. std0type        db      0       ;first video subsystem type
  24. ext0type        db      0       ;extended info on first subsystem
  25. std1type        db      0       ;second video subsystem type
  26. ext1type        db      0       ;extended info on second subsystem
  27. vidflag         record  monofound:1,colorfound:1
  28. egatype         vidflag <0,0>   ;Was a mono or color EGA found?
  29. ;
  30. ;video adapter codes (based on codes returned by VGA BIOS DC codes):
  31. ;-these codes are used when a VGA BIOS is not found and other tests
  32. ; need to be performed to determine video type
  33. ;-it was decided to use the VGA BIOS DC codes for simplicity
  34. ;-see findVGA procedure for list of VGA DCCs.
  35. ;
  36. NoDISP  equ     0       ;no display
  37. MONO    equ     1
  38. CGA     equ     2
  39. cEGA    equ     4       ;color EGA
  40. mEGA    equ     5       ;mono EGA
  41.  
  42. .code
  43.         org     100h            ;*.COM start offset
  44. start:
  45.         call    findVGA         ;look for a VGA or MCGA
  46.         comment \
  47.  
  48.         After executing VGA BIOS routines, the VGA BIOS itself will have
  49.         done all the work of determining what is installed so no need to
  50.         do any further tests. The "findVGA" subprocedure will set the CF
  51.         upon returning, if a VGA BIOS was found.
  52.  
  53.                 \
  54.         jc      endtests        ;found VGA/MCGA, end of tests
  55.         call    findEGA         ;look for an EGA
  56.         call    findCGA         ;look for a CGA
  57.         call    findMono        ;look for an MDA or HGC
  58. endtests:
  59.         call    write_msg       ;write found info to screen, set
  60.                                 ; errorlevel
  61.         mov     ah, 4ch         ;end program
  62.         int     21h
  63.  
  64. findVGA         proc
  65. comment *
  66.  
  67.         Purpose:
  68.         determine if a MCGA/VGA/SVGA display is installed
  69.  
  70.         Entry:
  71.         nothing
  72.  
  73.         Return:
  74.         CF set if found, clear if not
  75.  
  76.         *
  77.         mov     ax, 1A00h       ;get Displ Combo Code info
  78.         int     10h
  79.         cmp     al, 1Ah         ;VGA-only BIOS function
  80.         jne     noVGA           ; not supported => no VGA
  81. comment \
  82.  
  83.         Upon Return from Int 10h, AX=1A00h:
  84.         BL=primary adapter DCC
  85.         BH=secondary adapter DCC
  86.  
  87.         Values for display combination code:
  88.         00h no display
  89.         01h monochrome adapter w/ monochrome display
  90.         02h CGA w/ color display
  91.         03h reserved
  92.         04h EGA w/ color display
  93.         05h EGA w/ monochrome display
  94.         06h PGA w/ color display
  95.         07h VGA w/ monochrome analog display
  96.         08h VGA w/ color analog display
  97.         09h reserved
  98.         0Ah MCGA w/ digital color display
  99.         0Bh MCGA w/ monochrome analog display
  100.         0Ch MCGA w/ color analog display
  101.         FFh unknown display type
  102.  
  103.         \
  104.         push    bx              ;interpretDCC destroys contents of BH
  105.         call    interpretDCC    ;this proc looks for extended info
  106.         mov     [std0type], bl  ;save normal info
  107.         mov     [ext0type], bh  ;save extended info
  108.         pop     bx
  109.         push    bx
  110.         ;Since proc interpretDCC only works on info in BL, we must
  111.         ; exchange BL with BH.
  112.         xchg    bh, bl          
  113.         call    interpretDCC
  114.         mov     [std1type], bl  ;save normal info
  115.         mov     [ext1type], bh  ;save extended info
  116.         pop     bx
  117.         stc             ;found VGA/MCGA, so set CF before ret
  118.         jmp     endVGAtest
  119. noVGA:
  120.         clc
  121. endVGAtest:
  122.         ret
  123.  
  124.         interpretDCC    proc
  125.         comment *
  126.  
  127.                 Purpose:
  128.                 Interprets information returned by the DCC
  129.  
  130.                 Upon Entry:
  131.                 BL=normal DCC of desired video subsystem
  132.                 BH=will be destroyed, replaced with ext code
  133.  
  134.                 Upon Return:
  135.                 BL=normal DCC returned (MDA,CGA,EGA,PGA,MCGA,VGA,etc)
  136.                 BH=extended code (HGC,SVGA), 0 if none
  137.  
  138.                 *
  139.                 mov     bh, 0   ;Assume no extended attribs
  140.                 cmp     bl, 0   ;If 0, then no display card
  141.                 je      end_interpret
  142.                 cmp     bl, 1   ;Mono
  143.                 je      monotests
  144.                 jmp     CGAtests
  145.         monotests:
  146.         ;
  147.         ;If we find a monochrome adapter, then we need to do special
  148.         ; further tests to see if we have just an MDA or one of the
  149.         ; Hercules cards.
  150.         ;
  151.                 mov     bh, bl          ;save normal DCC in BH
  152.                 call    findHGC         ;MDA or HGC? value returned in
  153.                                         ; BL
  154.                 xchg    bh, bl          ;BL=normal,BH=extended
  155.                 jmp     end_interpret
  156.         CGAtests:
  157.                 cmp     bl, 2           ;CGA
  158.                 je      end_interpret
  159.                 cmp     bl, 6           ;EGA or PGA
  160.                 jbe     end_interpret
  161.                 cmp     bl, 8           ;BL=7,8: VGA
  162.                 ja      end_interpret
  163.         ;
  164.         ;If we find a VGA, then we need to do extra tests to see whose
  165.         ; VGA chipset it is.
  166.         ;
  167.                 mov     bh, bl          ;save BL in BH
  168.                 call    findSVGA        ;search for SVGA adapter
  169.                 xchg    bh, bl          ;BH=extended, BL=normal
  170.         end_interpret:
  171.                 ret
  172.                 endp
  173.         endp
  174.  
  175. findSVGA        proc
  176. comment *
  177.  
  178.         Purpose:
  179.         To search for specific SVGA types, including VESA compatibility.
  180.  
  181.         Entry:
  182.         Nothing
  183.  
  184.         Return:
  185.         BL=SVGA type
  186.  
  187.         *
  188. comment \
  189.  
  190.         List of SVGA types:
  191.         Brand           Type
  192.         -----           ----
  193.         ATI             1─┐
  194.         Ahead           2 │ These chipsets all have
  195.         Paradise        3 │ easily identifiable BIOS based
  196.         Oak             4 │ identification methods.
  197.         Genoa           5─┘
  198.         Cirrus          6─┐
  199.         Chips&Tech      7 │ These chipsets require complicated
  200.         Tseng           8 │ register twiddlings to identify
  201.         ZyMos           9 │ their presense.
  202.         Trident        10─┘
  203.         8514/A         11   -checks for HDILOAD.EXE only
  204.  
  205.         If a VESA BIOS is present, then add 128 to errorlevels.
  206.  
  207.         Note: The BIOS based id strings were obtained from Ralf Brown's
  208.         PD DOS Interrupts list (INTER32).
  209.  
  210.         The register level chipset tests were obtained through various
  211.         sources, including John Bridges' VGAKIT 5.0, and Andrew
  212.         Rossmann's INFOPLUS 1.55 source code. However, both gentlemen
  213.         appear to have gotten their info through the book "Advanced
  214.         Programmer's Guide to Super VGAs", by George Sutty and Steve
  215.         Blair. So lay credit wherever you like.
  216.  
  217.         \
  218.         noSVGA  equ     0
  219.         mov     bl, noSVGA      ;initially assume no SVGA
  220.         push    es              ;save current ES segment
  221.         mov     ax, 0C000h      ;set ES to VBIOS
  222.         mov     es, ax          ; segment (C000h)
  223.         ;
  224.         ;now testing for ATI chipset
  225.         ;
  226.         .data
  227.         ATIid   db      "761295520"
  228.         idlen   =       $-ATIid
  229.         ATI     equ     1
  230.         .code
  231.         mov     di, 31h         ;id string offset in ATI VBIOS
  232.         mov     si, offset ATIid
  233.         mov     cx, idlen
  234.         repe    cmpsb   ;comp each byte, exit if not matched
  235.         jne     noATI
  236.         mov     bl, ATI         ;ATI was found
  237.         jmp     endSVGAtests
  238. noATI:
  239.         ;
  240.         ;now testing for Ahead chipset
  241.         ;
  242.         .data
  243.         AHEADid db      "AHEAD"
  244.         idlen   =       $-AHEADid
  245.         AHEAD   equ     2
  246.         .code
  247.         mov     di, 25h ;id string offset in AHEAD VBIOS
  248.         mov     si, offset AHEADid
  249.         mov     cx, idlen
  250.         repe    cmpsb   ;comp each byte, exit if not matched
  251.         jne     noAHEAD
  252.         mov     bl, AHEAD       ;AHEAD was found
  253.         jmp     endSVGAtests
  254. noAHEAD:
  255.         ;
  256.         ;now testing for Paradise/WD chipset
  257.         ;
  258.         .data
  259.         PDISEid db      "VGA="
  260.         idlen   =       $-PDISEid
  261.         PDISE   equ     3
  262.         .code
  263.         mov     di, 7dh         ;id string offset in Pdise VBIOS
  264.         mov     si, offset PDISEid
  265.         mov     cx, idlen
  266.         repe    cmpsb
  267.         jne     noPDISE
  268.         mov     bl, PDISE       ;Paradise was found
  269.         jmp     endSVGAtests
  270. noPDISE:
  271.         ;
  272.         ;now testing for OAK chipset
  273.         ;
  274.         .data
  275.         OAKid   db      "OAK VGA"
  276.         idlen   =       $-PDISEid
  277.         OAK     equ     4
  278.         .code
  279.         mov     di, 8           ;id string offset in OAK VBIOS
  280.         mov     si, offset OAKid
  281.         mov     cx, idlen
  282.         repe    cmpsb
  283.         jne     noOAK
  284.         mov     bl, OAK         ;OAK was found
  285.         jmp     endSVGAtests
  286. noOAK:
  287.         ;
  288.         ;now testing for Genoa chipset
  289.         ;
  290.         ;the installation check for Genoa video adapters is the
  291.         ;signature 77h XXh 99h 66h at C000h:0037h, where XXh is
  292.         ;        00h for Genoa 6200/6300
  293.         ;        11h for Genoa 6400/6600
  294.         ;        22h for Genoa 6100
  295.         ;        33h for Genoa 5100/5200
  296.         ;        55h for Genoa 5300/5400
  297.         ;
  298.         .data
  299.         GENOAid db      77h,00h,99h,66h
  300.         idlen   =       $-GENOAid
  301.         GENOA   equ     5
  302.         .code
  303.         mov     di, 37h         ;id string offset in OAK VBIOS
  304.         mov     si, offset GENOAid
  305.         mov     cx, idlen
  306.         repe    cmpsb
  307.         pushf                   ;save flags
  308.         cmp     cx, idlen-2     ;did mismatch occur after 2nd byte?
  309.         je      contGENOA       ;yes? continue test at next byte
  310.         popf                    ;restore flags
  311.         jmp     discontGENOA
  312. contGENOA:
  313.         popf                    ;restore flags
  314.         repe    cmpsb           ;continue tests where it left off
  315. discontGENOA:
  316.         jne     noGENOA
  317.         mov     bl, GENOA
  318.         jmp     endSVGAtests
  319. noGENOA:
  320.         ;
  321.         ;The following chipsets require register tests, and cannot be
  322.         ; identified through the BIOS:
  323.         ;
  324.         ;test for CIRRUS chipset (register)
  325.         ;
  326.         call    CIRRUStest
  327.         cmp     bl, 0           ;if BL=0, Cirrus wasn't found
  328.         jne     endSVGAtests
  329.         ;
  330.         ;test for ZyMos chipset (register)
  331.         ;
  332.         call    ZYMOStest
  333.         cmp     bl, 0           ;C&T was not found
  334.         jne     endSVGAtests
  335.         ;
  336.         ;test for TSENG chipset (register)
  337.         ;
  338.         call    TSENGtest
  339.         cmp     bl, 0           ;Tseng was not found
  340.         jne     endSVGAtests
  341.         ;
  342.         ;test for Trident chipset (register)
  343.         ;
  344.         call    TridentTest
  345.         cmp     bl, 0           ;Trident wasn't found
  346.         jne     endSVGAtests
  347.         call    Test8514
  348.         cmp     bl, 0
  349.         jne     endSVGAtests    ;8514/A wasn't found
  350.         ;
  351.         ;test for C&T chipset (register)
  352.         ;
  353.         ;Note: the C&T test routine has been moved to the end, because
  354.         ; it seems to cause the most lockups.
  355.         ;
  356.         call    CHIPStest
  357. endSVGAtests:
  358.         ;
  359.         ;test to see if VESA BIOS is installed
  360.         ;
  361.         .data
  362.         VESAbuf db      256 dup(?)      ;VESA information buffer
  363.         .code
  364.         pop     es
  365.         mov     ax, 4f00h
  366.         mov     di, offset VESAbuf
  367.         int     10h             ;VESA: get SVGA info
  368.         cmp     ax, 004fh       ;if VESA installed this should work
  369.         jne     noVESA
  370.         ;
  371.         ; If VESABIT of the record, SVGATYPE, is set, then a VESA
  372.         ; BIOS was found. The rest of the record just records what
  373.         ; type of SVGA was found, regardless of VESA.
  374.         ;
  375.         svgatype        record  vesabit:1,svgabits:7
  376.  
  377.         or      bl, mask vesabit        ;turn on VESAbit, in ext code
  378. noVESA:
  379.         ret
  380.  
  381.         CIRRUStest      proc
  382.         comment *
  383.  
  384.                 Purpose:
  385.                 Register-level test for CIRRUS chipset
  386.  
  387.                 Entry:
  388.                 BH=current normal DCC
  389.  
  390.                 Return:
  391.                 BL=SVGA code
  392.                 *
  393.                 CIRRUS  equ     6
  394.                 push    bx      ;save BH
  395.                 mov     dx, 3B4h;assume DX=mono VGA selection port
  396.                 cmp     bh, 8   ;if BH=8, color; BH=7, mono
  397.                 je      color_cirrus
  398.                 add     dx, 020h;if color, add 20h to select port addr
  399.         color_cirrus:
  400.                 mov     al, 0Ch ;Start Addr High register
  401.                 out     dx, al
  402.                 inc     dx      ;DX=data port
  403.                 in      al, dx  ;read register
  404.                 mov     ah, al  ;save
  405.                 xchg    al, ah  ;swap back
  406.                 push    ax      ;save port value
  407.                 push    dx      ;save port addr
  408.                 xor     al, al
  409.                 out     dx, al  ;zero Start Addr High reg
  410.                 dec     dx      ;back to selection port
  411.                 mov     al, 1Fh
  412.                 out     dx, al  ;select special Cirrus ID reg
  413.                 inc     dx      ;back to data port
  414.                 in      al, dx  ;read ID reg value
  415.                 mov     ah, al  ;save it in AH
  416.                 mov     bh, al  ;save again in BH
  417.                 mov     dx, 3c4h;addr of special seq'ncr/ext'ns select port
  418.                 mov     al, 6   ;extensions control reg
  419.                 mov     cl, 4   ;get ready to swap the nibbles in AX
  420.                 ror     bh, cl  ;nibble swap computes ext reg disable val
  421.                 mov     ax, bx
  422.                 out     dx, ax  ;disable extensions
  423.                 inc     dx      ;seq/ext data port
  424.                 in      al, dx  ;read back enable flag
  425.                 or      al, al  ;disabled?
  426.                 jnz     noCIRRUS
  427.                 dec     dx      ;seq/ext select port
  428.                 mov     bh, al  ;save AL
  429.                 mov     al, 6   ;extensions control reg
  430.                 out     dx, al
  431.                 inc     dx
  432.                 mov     al, ah  ;restore ID reg value
  433.                 out     dx, al  ;reenable ext regs
  434.                 in      al, dx  ;read back ext reg
  435.                 cmp     al, 1   ;enabled?
  436.                 jne     noCIRRUS
  437.                 ror     bh, cl  ;nibble swap to compute enable ext reg val
  438.                 dec     dx
  439.                 mov     ax, bx
  440.                 out     dx, ax  ;ext enable
  441.                 inc     dx
  442.                 in      al, dx
  443.                 cmp     al, 1
  444.                 jne     noCIRRUS
  445.                 mov     bl, CIRRUS      ;CIRRUS was found
  446.         noCIRRUS:
  447.                 pop     dx
  448.                 dec     dx      ;point select reg
  449.                 pop     ax
  450.                 out     dx, ax  ;restore to orig state
  451.                 pop     ax      ;restore BH
  452.                 mov     bh, ah
  453.                 ret
  454.                 endp
  455.  
  456.         CHIPStest       proc
  457.         comment *
  458.  
  459.                 Purpose:
  460.                 Register-level test for C&T VGA chipset
  461.  
  462.                 Entry:
  463.                 BH=current normal DCC
  464.  
  465.                 Return:
  466.                 BL=SVGA code
  467.  
  468.                 Note:
  469.                 This particular test appears to lockup my system, with
  470.                 an ATI VGAWonder card installed, after the first port
  471.                 write. I have no idea if this lockup is due to the
  472.                 presence of the ATI or some other component in my
  473.                 motherboard. So be forewarned: always do the ATI test
  474.                 first, which is safely BIOS-based, before you do this
  475.                 test. In fact you might want to save this test for the
  476.                 last of all the tests you do.
  477.  
  478.                 *
  479.  
  480.         CHIPS   equ     7
  481.         ;place VGA in setup mode
  482.                 cli
  483.                 mov     dx,46e8h        ;address of setup control reg
  484.                 in      al,dx
  485.                 or      al,10h          ;turn on setup bit
  486.                 out     dx,al           ;go to setup mode
  487.         ;enable extended register bank
  488.                 mov     dx,103h         ;extended reg address
  489.                 in      al,dx
  490.                 or      al,80h          ;turn enable bit on
  491.                 out     dx,al
  492.         ;read global ID
  493.                 mov     dx,104h         ;global ID reg
  494.                 in      al,dx
  495.                 mov     ah,al           ;save
  496.         ;place vga in normal mode
  497.                 mov     dx,46e8h
  498.                 in      al,dx
  499.                 and     al,03fh
  500.                 out     dx,al
  501.                 sti
  502.         ;read version extended register
  503.                 mov     dx,3d6h
  504.                 mov     al,0
  505.                 out     dx,al           ;select version register
  506.                 inc     dx
  507.                 in      al,dx
  508.                 cmp     ah,5ah          ;check for CTI ID
  509.                 jne     notcti
  510.                 and     al,0f0h         ;adjust chip id
  511.                 shr     al,1
  512.                 shr     al,1
  513.                 shr     al,1
  514.                 shr     al,1
  515.                 cmp     al,2            ;only 0, 1 and 3 are good
  516.                 je      notcti
  517.                 cmp     al,4
  518.                 jge     notcti
  519.                 cmp     al,3
  520.                 je      notcti
  521.                 mov     bl, CHIPS       ;return SVGA info
  522.         notcti:
  523.                 ret
  524.                 endp
  525.  
  526.         TSENGtest       proc
  527.         comment *
  528.  
  529.                 Purpose:
  530.                 Register-level test for Tseng VGA chipset
  531.  
  532.                 Entry:
  533.                 BH=current normal DCC
  534.  
  535.                 Return:
  536.                 BL=SVGA code
  537.                 *
  538.         TSENG   equ     8
  539.                 mov     dx,3cdh         ;page select reg
  540.                 in      al,dx
  541.                 mov     ah,al           ;save
  542.                 and     al,0c0h         ;save some bits
  543.                 or      al,55h          ;test value one
  544.                 out     dx,al           ;write it
  545.                 in      al,dx
  546.                 cmp     al,55h          ;same?
  547.                 jne     nottseng
  548.                 mov     al,0aah         ;test value two
  549.                 out     dx,al
  550.                 in      al,dx
  551.                 cmp     al,0aah         ;same
  552.                 jne     nottseng
  553.                 mov     al,ah           ;restore original settings
  554.                 out     dx,al
  555.                 mov     al,1
  556.         end_tsengck:
  557.                 mov     bl, TSENG       ;found a TSENG
  558.         nottseng:
  559.                 ret
  560.                 endp
  561.  
  562.         ZYMOStest       proc
  563.         comment *
  564.  
  565.                 Purpose:
  566.                 Register-level test for ZyMos VGA chipset
  567.  
  568.                 Entry:
  569.                 BH=current normal DCC
  570.  
  571.                 Return:
  572.                 BL=SVGA code
  573.  
  574.                 *
  575.         ZyMos   equ     9
  576.                 mov     dx,3c4h         ;extended reg bank
  577.                 mov     al,0bh          ;version reg
  578.                 out     dx,al
  579.                 inc     dx
  580.                 in      al,dx           ;get version
  581.                 and     al,0fh
  582.                 cmp     al,2
  583.                 jne     end_zymosck     ;not found
  584.                 mov     bl, ZyMos       ;found one
  585.         end_zymosck:
  586.                 ret
  587.                 endp
  588.  
  589.         TridentTest     proc
  590.         comment *
  591.  
  592.                 Purpose:
  593.                 Register level test for Trident VGA chipset
  594.  
  595.                 Entry:
  596.                 BH=current normal DCC
  597.  
  598.                 Return:
  599.                 BL=SVGA code
  600.  
  601.                 Note:
  602.                 -Thanks to John Olson, of Fidonet 1:106/888, of the
  603.                 Fidonet 80XXX assembly language echo, who supplied this
  604.                 routine from "Programmer's Guide to the EGA and VGA
  605.                 Cards", by Richard F. Ferraro.
  606.  
  607.                 *
  608.                 Trident equ     10
  609.                 MOV     DX,3C4H
  610.                 MOV     AL,0EH          ; Read mode control #1 Register
  611.                 OUT     DX,AL
  612.                 INC     DX
  613.                 IN      AL,DX           ; Read old value
  614.                 XOR     AL,2
  615.                 PUSH    AX
  616.                 MOV     AL,0            ; Write new value bit 1=0, all
  617.                                         ;other bits =0
  618.                 OUT     DX,AL
  619.                 IN      AL,DX           ; Read new value
  620.                 AND     AL,0FH
  621.                 CMP     AL,2            ; Check for Trident
  622.                 POP     AX              ; Old value
  623.                 OUT     DX,AL           ; Restore old value
  624.                 JNZ     NOT_T
  625.                 mov     bl, Trident     ;found one
  626.         not_t:
  627.                 ret
  628.                 endp
  629.  
  630.         Test8514        proc
  631.         comment *
  632.  
  633.                 Purpose:
  634.                 Installation check for 8514/A's HDILOAD.EXE
  635.  
  636.                 Entry:
  637.                 BH=current normal DCC
  638.  
  639.                 Return:
  640.                 BL=SVGA code
  641.                 AX,CX,DX destroyed
  642.  
  643.                 *
  644.                 _8514   equ     11
  645.                 ;
  646.                 ;If HDILOAD installed then CX and/or DX will be modified
  647.                 ; as CX:DX->function entry point array
  648.                 ;
  649.                 mov     ax, 105h
  650.                 mov     cx, 0
  651.                 mov     dx, 0
  652.                 int     7Fh             ;installation check
  653.                 cmp     cx, 0           ;if CX didn't change
  654.                 je      no8514
  655.                 mov     bl, _8514
  656.         no8514:
  657.                 ret
  658.                 endp
  659.  
  660.         endp
  661.  
  662. findEGA proc
  663. comment *
  664.  
  665.         Purpose:
  666.         To find an EGA
  667.  
  668.         *
  669.         mov     ah, 12h
  670.         mov     bx, 0FF10h
  671.         int     10h             ;for EGA BIOS+ only
  672.         cmp     bh, 0FFh        ;if BH remains unchanged
  673.         je      endEGAtest      ; then EGA BIOS not installed
  674.         cmp     bh, 0           ;BH=0, if color EGA
  675.         jne     EGAmono
  676.         mov     [egatype], mask colorfound
  677.         mov     bl, cEGA        ;EGA w/ color disp
  678.         mov     dx, 3D4h        ;color port addr
  679.         call    determine_subsystem
  680.         jmp     endEGAtest
  681. EGAmono:
  682.         mov     [egatype], mask monofound
  683.         mov     bl, mEGA        ;EGA w/ mono disp
  684.         mov     dx, 3B4h        ;mono port addr
  685.         call    determine_subsystem
  686. endEGAtest:
  687.         ret
  688.         endp
  689.  
  690. findCGA         proc
  691. comment *
  692.  
  693.         Purpose:
  694.         To find a CGA
  695.  
  696.         *
  697.         test    [egatype], mask colorfound      ;is color EGA present?
  698.         jne     endCGAtest      ;yes, then skip test
  699.         mov     dx, 3D4h        ;DX=CGA 6845 CRTC port addr
  700.         call    find6845
  701.         jc      endCGAtest      ;didn't find CGA
  702.         mov     bl, CGA         ;ie. found CGA
  703.         call    determine_subsystem
  704. endCGAtest:
  705.         ret
  706.         endp
  707.  
  708. findMono        proc
  709. comment *
  710.  
  711.         Purpose:
  712.         To find a Mono adapter
  713.  
  714.         *
  715.         test    [egatype], mask monofound       ;is mono EGA present?
  716.         jne     EndMonotest     ;yes, then skip test
  717.         mov     dx, 3B4h        ;DX=Mono 6845 CRTC port addr
  718.         call    find6845
  719.         jc      EndMonoTest     ;didn't find MDA
  720.         ;
  721.         ;We've found a mono adapter, now it's time to find out
  722.         ; if it's a Hercules-compatible monographics adapter.
  723.         ;
  724.         mov     bl, MONO        ;found MDA
  725.         call    determine_subsystem
  726.         jc      mono_is_2nd     ;MDA was 2nd system
  727.         call    findHGC         ;is 1st a Herc?
  728.         mov     [ext0type], bl
  729.         jmp     EndMonoTest
  730. mono_is_2nd:
  731.         call    findHGC         ;is 2nd a Herc?
  732.         mov     [ext1type], bl
  733. EndMonoTest:
  734.         ret
  735.         endp
  736.  
  737. findHGC proc
  738. comment *
  739.  
  740.         Purpose:
  741.         To determine if MDA found is also a Herc of some sort
  742.  
  743.         Enter:
  744.         nothing
  745.  
  746.         Return:
  747.         BL=Herc type
  748.  
  749.         *
  750.         NoHerc  equ     0       ;no Hercules
  751.         Herc    equ     1       ;regular Hercules
  752.         HercP   equ     2       ;Hercules Plus
  753.         HercIC  equ     3       ;Hercules InColor
  754.         comment \
  755.                 Hercs are identified from normal MDA by bit 7, vertical
  756.                 sync, on 6845 Status Port which is changeable only on
  757.                 Hercs.
  758.  
  759.                 Hercs are identified from each other with bits 4-6 in
  760.                 Status Port. On an regular Herc, they are 000b, on
  761.                 Herc+, they are 001b, and on InColor, they are 101b.
  762.  
  763.                 Each bit is kept track of in the record, HGCStatus.
  764.                 \
  765.         HGCStatus       record  vsync:1,HGCid:3,miscbits:4
  766.         mov     dx, 3BAh        ;status port
  767.         in      al, dx
  768.         and     al, mask vsync
  769.         mov     ah, al          ;store current vsync status in AH
  770.         mov     cx, 8000h       ;loop 32768 times
  771. teststatusbit:
  772.         in      al, dx
  773.         and     al, mask vsync
  774.         cmp     ah, al
  775.         loope   teststatusbit   ;keep looping as long as they are equal
  776.         jne     HercIDs         ;if vsync changed, is a Herc
  777.         mov     bl, NoHerc      ;was not a Herc
  778.         jmp     EndHercTests
  779. HercIDs:
  780.         in      al, dx          ;read status port again
  781.         and     al, mask HGCid  ;mask all but bits 4-6
  782.         cmp     al, HGCStatus <0,001b,0>        ;indicates HGC+
  783.         je      isPlus
  784.         mov     bl, Herc        ;is a regular Herc, for now
  785.         cmp     al, HGCStatus <0,101b,0>        ;indicates InColor
  786.         jne     EndHercTests    ;didn't find InColor
  787.         mov     bl, HercIC      ;is an InColor
  788.         jmp     EndHercTests
  789. isPlus:
  790.         mov     bl, HercP       ;is a Herc Plus (Ramfonts)
  791. EndHercTests:
  792.         ret
  793.         endp
  794.  
  795. determine_subsystem     proc
  796. comment *
  797.         Purpose:
  798.         To determine if currently tested subsystem is primary or secondary
  799.  
  800.         Entry:
  801.         BL=subsystem DCC value to input in memory
  802.         DX=port address to compare against
  803.  
  804.         Return:
  805.         CF clear if primary system, set if secondary
  806.         *
  807.         push    ax              ;save AX
  808.         push    es              ;save ES
  809.         mov     ax, 40h         ;set ES to
  810.         mov     es, ax          ; BIOS data segment
  811.         mov     ax, es:[63h]    ;AX=active Vid CRTC base addr
  812.         cmp     ax, dx          ;is current = default?
  813.         pop     es              ;restore ES
  814.         pop     ax              ;restore AX
  815.         jne     _2ndsystem      ;if not default, must be 2nd subsystem
  816.         mov     [std0type], bl  ;store as 1st system
  817.         clc                     ;is primary, so clear CF
  818.         jmp     end_det_sys
  819. _2ndsystem:
  820.         mov     [std1type], bl  ;store as 2nd system
  821.         stc                     ;is secondary, so set CF
  822. end_det_sys:
  823.         ret
  824.         endp
  825.  
  826. find6845        proc
  827. comment *
  828.         Purpose:
  829.         Detect if a 6845-compatible CRTC controller is present at port
  830.         address given in DX
  831.  
  832.         Entry:
  833.         DX=CRTC base port address to test
  834.  
  835.         Return:
  836.         CF clear if successful, set if not
  837.         *
  838.         push    dx
  839.         push    ax
  840.         mov     al, 0Fh
  841.         out     dx, al  ;select 6845 reg 0Fh (cursor low)
  842.         inc     dx
  843.         in      al, dx  ;AL=current cursor low val
  844.         mov     ah, al  ;save AL in AH
  845.         mov     al, 66h ;AL=set some arbitrary val
  846.         out     dx, al  ;write to 6845
  847.         mov     cx, 100h
  848.         loop    $       ;loop 100h times
  849.         in      al, dx
  850.         xchg    ah, al  ;AH=returned value
  851.                         ;AL=original value
  852.         out     dx, al  ;restore original value
  853.         cmp     ah, 66h ;did 6845 respond?
  854.         je      end6845
  855.         stc             ;set CF if 6845 not there
  856. end6845:
  857.         pop     ax
  858.         pop     dx
  859.         ret
  860.         endp
  861.  
  862. write_msg       proc
  863. comment *
  864.  
  865.         Purpose:
  866.         To display video adapter information to Stdout, and return an
  867.         errorlevel based on command line parameters.
  868.  
  869.         *
  870. .data
  871. CRLF    equ     13,10,"$"
  872. copyright       db      "VIDTYPE v1.1 (c) 1992, Yousuf J. Khan",CRLF
  873. std_msg db      "Standard video information:",CRLF
  874. ext_msg db      "Extended video information:",CRLF
  875. vid1msg db      "Primary video subsystem:",CRLF
  876. vid2msg db      "Secondary video subsystem:",CRLF
  877. ;Standard video adapter types (based on VGA BIOS DCCs)
  878. DCC00   db      "no display",CRLF
  879. DCC01   db      "monochrome adapter w/ monochrome display",CRLF
  880. DCC02   db      "CGA w/ color display",CRLF
  881. DCC03   db      "reserved",CRLF
  882. DCC04   db      "EGA w/ color display",CRLF
  883. DCC05   db      "EGA w/ monochrome display",CRLF
  884. DCC06   db      "PGA w/ color display",CRLF
  885. DCC07   db      "VGA w/ monochrome analog display",CRLF
  886. DCC08   db      "VGA w/ color analog display",CRLF
  887. DCC09   db      "reserved",CRLF
  888. DCC0A   db      "MCGA w/ digital color display",CRLF
  889. DCC0B   db      "MCGA w/ monochrome analog display",CRLF
  890. DCC0C   db      "MCGA w/ color analog display",CRLF
  891. DCCFF   db      "unknown display type",CRLF
  892. stdmsgtbl       dw      DCC00
  893.                 dw      DCC01
  894.                 dw      DCC02
  895.                 dw      DCC03
  896.                 dw      DCC04
  897.                 dw      DCC05
  898.                 dw      DCC06
  899.                 dw      DCC07
  900.                 dw      DCC08
  901.                 dw      DCC09
  902.                 dw      DCC0A
  903.                 dw      DCC0B
  904.                 dw      DCC0C
  905.                 dw      DCCFF
  906. ;Extended video adapter types (various Hercs & Super VGAs)
  907. HG      equ     "Hercules "
  908. SV      equ     "Super VGA: "
  909. EXT00   db      "no extended info available",CRLF
  910. HGC00   db      HG,"standard",CRLF
  911. HGC01   db      HG,"Plus (Ramfonts)",CRLF
  912. HGC02   db      HG,"InColor",CRLF
  913. HGCmsgtbl       dw      EXT00   ;no Herc
  914.                 dw      HGC00
  915.                 dw      HGC01
  916.                 dw      HGC02
  917. VGA00   db      SV,"ATI",CRLF
  918. VGA01   db      SV,"AHEAD",CRLF
  919. VGA02   db      SV,"Paradise",CRLF
  920. VGA03   db      SV,"Oak",CRLF
  921. VGA04   db      SV,"Genoa",CRLF
  922. VGA05   db      SV,"Cirrus",CRLF
  923. VGA06   db      SV,"Chips & Tech",CRLF
  924. VGA07   db      SV,"TSENG",CRLF
  925. VGA08   db      SV,"ZyMos",CRLF
  926. VGA09   db      SV,"Trident TVGA",CRLF
  927. VGA10   db      SV,"8514/A",CRLF
  928. VGAmsgtbl       dw      EXT00   ;no SVGA
  929.                 dw      VGA00
  930.                 dw      VGA01
  931.                 dw      VGA02
  932.                 dw      VGA03
  933.                 dw      VGA04
  934.                 dw      VGA05
  935.                 dw      VGA06
  936.                 dw      VGA07
  937.                 dw      VGA08
  938.                 dw      VGA09
  939.                 dw      VGA10
  940. spaces  db      "    $"   ;three space indentation
  941. VESAmsg db      "VESA BIOS present",CRLF
  942.  
  943. .code
  944.  
  945. DOSMSG  macro   msg_offset
  946.         mov     ah, 9
  947.         mov     dx, offset msg_offset
  948.         int     21h
  949.         endm
  950.  
  951. TYPEmsg macro   base, index
  952.         xor     bx, bx
  953.         add     bl, [index]
  954.         ;
  955.         ;mask out VESA bit in "svgatype" record
  956.         ; both forms of the AND below are the same
  957.         ;
  958. ;        and     bl, mask svgabits      ;mask bottom 7 bits, or
  959.         and     bl, not mask vesabit    ; don't mask 8th bit
  960.         mov     si, bx
  961.         shl     si, 1                   ;mult offsets by 2
  962.         mov     bx, offset base
  963.         mov     dx, [bx][si]
  964.         mov     ah, 9
  965.         int     21h
  966.         endm
  967.  
  968. INDENT  macro   num
  969.         ;
  970.         ;puts indentations in text printed to screen
  971.         ;
  972.         rept    num
  973.                 mov     dx, offset spaces
  974.                 mov     ah, 9
  975.                 int     21h
  976.                 endm
  977.         endm
  978.  
  979.         DOSMSG  copyright
  980.         INDENT  1
  981.         DOSMSG  vid1msg
  982.         INDENT  2
  983.         DOSMSG  std_msg
  984.         INDENT  3
  985.         TYPEmsg stdmsgtbl, std0type
  986.         INDENT  2
  987.         DOSMSG  ext_msg
  988.         INDENT  3
  989.         cmp     [std0type], 1           ;is it MDA?
  990.         je      extmono1                ;yes, it's MDA
  991.         TYPEmsg vgamsgtbl, ext0type
  992.         mov     bl, ext0type
  993.         and     bl, mask vesabit        ;was VESA bit set?
  994.         je      _2nd_vid_adapter        ;no VESA
  995.         INDENT  3
  996.         DOSMSG  VESAmsg                 ;display VESA message
  997.         jmp     _2nd_vid_adapter
  998. extmono1:
  999.         TYPEmsg hgcmsgtbl, ext0type
  1000. _2nd_vid_adapter:
  1001.         INDENT  1
  1002.         DOSMSG  vid2msg
  1003.         INDENT  2
  1004.         DOSMSG  std_msg
  1005.         INDENT  3
  1006.         TYPEmsg stdmsgtbl, std1type
  1007.         INDENT  2
  1008.         DOSMSG  ext_msg
  1009.         INDENT  3
  1010.         cmp     [std1type], 1           ;is it MDA or VGA?
  1011.         je      extmono2                ;it's MDA
  1012.         TYPEmsg vgamsgtbl, ext1type
  1013.         mov     bl, ext1type
  1014.         and     bl, mask vesabit        ;was VESA bit set?
  1015.         je      end_display             ;no VESA
  1016.         INDENT  3
  1017.         DOSMSG  VESAmsg                 ;display VESA message
  1018.         jmp     end_display
  1019. extmono2:
  1020.         TYPEmsg hgcmsgtbl, ext1type
  1021. end_display:
  1022.         call    return_errorlevel;return errorlevel
  1023. ;        mov     al, [std0type]  ;return errorlevel
  1024.         ret
  1025.         endp
  1026.  
  1027. return_errorlevel       proc
  1028. comment *
  1029.  
  1030.         Purpose:
  1031.         To scan command-line for errorlevel return parameters
  1032.  
  1033.         eg: vidtype
  1034.             vidtype e
  1035.             vidtype 2
  1036.             vidtype e2
  1037.             vidtype 2E
  1038.  
  1039.                 Command-line parameters:
  1040.                 none    errorlevel based on prim video subsys
  1041.                 "e"     errorlevel based on prim ext video code
  1042.                 "2"     errorlevel based on sec video subsys
  1043.                 both    errorlevel based on sec ext video code
  1044.         *
  1045.         .data
  1046.         cmdln_params    record  secondary:1, extended:1
  1047.         cmdflags        cmdln_params    <0,0>
  1048.         .code
  1049.         ;
  1050.         ;start parsing the command line
  1051.         ;
  1052. lookfor macro   char
  1053.         mov     al, char
  1054.         mov     di, 81h
  1055.         repne   scasb
  1056.         endm
  1057.  
  1058.         mov     si, 80h ;point to command-line in PSP
  1059.         lodsb           ;get length of cmd-line in AL
  1060.         ;
  1061.         ;looking for little "e"
  1062.         ;
  1063.         push    ds
  1064.         pop     es      ;ES=DS
  1065.         xor     cx, cx
  1066.         mov     cl, al  ;number of interations
  1067.         push    cx      ;save CX
  1068.         lookfor "e"
  1069.         jne     SeekBigE
  1070.         or      [cmdflags], mask extended       ;set the flag
  1071.         jmp     SeekTwo ;start looking for "2"
  1072. SeekBigE:
  1073.         ;
  1074.         ;looking for big "E"
  1075.         ;
  1076.         pop     cx      ;restore CX
  1077.         push    cx      ;save it again
  1078.         lookfor "E"
  1079.         jne     SeekTwo
  1080.         or      [cmdflags], mask extended       ;set the flag
  1081. SeekTwo:
  1082.         ;
  1083.         ;looking for "2"
  1084.         ;
  1085.         pop     cx      ;restore CX
  1086.         lookfor "2"
  1087.         jne     send_err00
  1088.         or      [cmdflags], mask secondary      ;set the flag
  1089. send_err00:
  1090.         cmp     [cmdflags], cmdln_params <0,0>  ;neither flag set
  1091.         jne     send_err01
  1092.         mov     al, [std0type]
  1093.         jmp     endret_err
  1094. send_err01:
  1095.         cmp     [cmdflags], cmdln_params <0,1>  ;ext flag set
  1096.         jne     send_err10
  1097.         mov     al, [ext0type]
  1098.         jmp     endret_err
  1099. send_err10:
  1100.         cmp     [cmdflags], cmdln_params <1,0>  ;sec flag set
  1101.         jne     send_err11
  1102.         mov     al, [std1type]
  1103.         jmp     endret_err
  1104. send_err11:     ;both ext and sec flags set
  1105.         mov     al, [ext1type]
  1106. endret_err:
  1107.         ret
  1108.         endp
  1109.  
  1110.         end     start
  1111.